package br.museu.spring.config;

import java.util.Properties;

import javax.sql.DataSource;

import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.hibernate4.HibernateTransactionManager;
import org.springframework.orm.hibernate4.LocalSessionFactoryBean;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.JstlView;
import org.springframework.web.servlet.view.UrlBasedViewResolver;

import br.museu.dao.basic.EventoDAO;
import br.museu.dao.basic.TicketDAO;
import br.museu.dao.basic.UsuarioDAO;
import br.museu.dao.basic.intefaces.IEventoDAO;
import br.museu.dao.basic.intefaces.ITicketDAO;
import br.museu.dao.basic.intefaces.IUsuarioDAO;
import br.museu.model.Usuario;
import br.museu.negocio.EventoNegocio;
import br.museu.negocio.TicketNegocio;
import br.museu.negocio.UsuarioNegocio;
import br.museu.negocio.interfaces.IEventoNegocio;
import br.museu.negocio.interfaces.ITicketNegocio;
import br.museu.negocio.interfaces.IUsuarioNegocio;

@Configuration
@EnableTransactionManagement
@ComponentScan("br.museu.controller")
@EnableWebMvc
@PropertySource(value = { "classpath:application.properties" })
public class Config extends WebMvcConfigurerAdapter {

	@Bean
	public UrlBasedViewResolver setupViewResolver() {
		UrlBasedViewResolver resolver = new UrlBasedViewResolver();
		resolver.setPrefix("/views/");
		resolver.setSuffix(".jsp");
		resolver.setViewClass(JstlView.class);
		return resolver;
	}

	@Override
	public void addResourceHandlers(ResourceHandlerRegistry registry) {
		registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
		registry.addResourceHandler("/css/**").addResourceLocations("/css/");
		registry.addResourceHandler("/js/**").addResourceLocations("/js/");
	}

	// Models
	@Bean
	public Usuario usuario() {
		return new Usuario();
	}

	// Negocio
	@Bean
	public IUsuarioNegocio usuarioNegocio() {
		return new UsuarioNegocio();
	}

	@Bean
	IEventoNegocio eventoNegocio() {
		return new EventoNegocio();
	}

	@Bean
	ITicketNegocio ticketNegocio() {
		return new TicketNegocio();
	}

	// DAOS
	@Bean
	public IUsuarioDAO usuarioDao() {
		return new UsuarioDAO();
	}

	@Bean
	public IEventoDAO eventoDao() {
		return new EventoDAO();
	}

	@Bean
	public ITicketDAO ticketDao() {
		return new TicketDAO();
	}

	@Autowired
	private Environment environment;

	@Bean
	public LocalSessionFactoryBean sessionFactory() {
		LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
		sessionFactory.setDataSource(dataSource());
		sessionFactory.setPackagesToScan(new String[] { "br.museu.model" });
		sessionFactory.setHibernateProperties(hibernateProperties());
		return sessionFactory;
	}

	@Bean
	public DataSource dataSource() {
		DriverManagerDataSource dataSource = new DriverManagerDataSource();
		dataSource.setDriverClassName(environment.getRequiredProperty("jdbc.driverClassName"));
		dataSource.setUrl(environment.getRequiredProperty("jdbc.url"));
		dataSource.setUsername(environment.getRequiredProperty("jdbc.username"));
		dataSource.setPassword(environment.getRequiredProperty("jdbc.password"));
		return dataSource;
	}

	private Properties hibernateProperties() {
		Properties properties = new Properties();
		properties.put("hibernate.dialect", environment.getRequiredProperty("hibernate.dialect"));
		properties.put("hibernate.show_sql", environment.getRequiredProperty("hibernate.show_sql"));
		properties.put("hibernate.format_sql", environment.getRequiredProperty("hibernate.format_sql"));
		properties.put("hibernate.hbm2ddl.auto", environment.getRequiredProperty("hibernate.hbm2ddl.auto"));
		return properties;
	}

	@Bean
	@Autowired
	public HibernateTransactionManager transactionManager(SessionFactory s) {
		HibernateTransactionManager txManager = new HibernateTransactionManager();
		txManager.setSessionFactory(s);
		return txManager;
	}
}
